package com.huizhan.web.common.utils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.huizhan.web.common.annotation.Excel;
import com.huizhan.web.common.enums.ErrorCode;
import com.huizhan.web.common.exception.BizException;
import com.huizhan.web.common.exception.SystemException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

import java.util.Date;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

 

/**
 * <p>
 * excel 工具类
 * </p>
 *
 * @author <a href="mailto:yangyanrui@yidianlife.com">xiaoyang</a>
 * @version V0.0.1
 * @date 2019年09月12日
 */
@Slf4j
public class ExcelUtil {
    /**
     * xls 后缀
     */
    public final static String XLS = "xls";
    /**
     * xlsx 后缀
     */
    public final static String XLS_X = "xlsx";
    /**
     * 列不对等
     */
    private final static String ROW_NUM_ERROR = "列不对等！";
    /**
     * 文件不存在
     */
    private final static String FILE_NOT_ERROR = "文件不存在！";
    /**
     * 表头错误
     */
    private final static String NAME_ERROR = "表头错误！";
    /**
     * 表头错误
     */
    private final static String ANNOTATION_ERROR = "注解空异常！";
    /**
     * 实体空异常
     */
    private final static String BEAN_ERROR = "实体空异常！";
    /**
     * 科学计数
     */
    private final static String E = "e";


    /**
     * 传入文本对象输出list集合（导入）
     *
     * @param file  流文件
     * @param clazz 要转义成的类对象
     * @return
     */
    public static <T> List<T> importExcel(MultipartFile file, Class<T> clazz) {
        // 检查文件
        checkFile(file);
        // 获得HSSFWorkbook工作薄对象
        Workbook workbook = getWorkBook(file);
        List<T> list = new ArrayList<T>();
        //获取对象总数量
        Field[] fields = getSortFields(clazz);
        //对象字段排序
        Arrays.sort(fields, (a, b) -> {
            return a.getAnnotation(Excel.class).orderNum() - b.getAnnotation(Excel.class).orderNum();
        });
        if (workbook != null) {
            for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
                // 获得当前sheet工作表
                Sheet sheet = workbook.getSheetAt(sheetNum);
                if (sheet == null || sheet.getLastRowNum() == 0) {
                    continue;
                }
                // 获取当前sheet工作表的列总数
                int firstLine = sheet.getRow(0).getPhysicalNumberOfCells();
                if (fields.length != firstLine) {
                    throw new BizException(ErrorCode.SYS_EXCEPTION.getCode(), ROW_NUM_ERROR);
                }
                // 获得当前sheet的开始行
                int firstRowNum = sheet.getFirstRowNum();
                // 获得当前sheet的结束行
                int lastRowNum = sheet.getLastRowNum();
                // 循环所有行
                for (int rowNum = firstRowNum; rowNum <= lastRowNum; rowNum++) {
                    // 获得当前行
                    Row row = sheet.getRow(rowNum);
                    if (row == null) {
                        continue;
                    }
                    Object obj;
                    try {
                        obj = clazz.newInstance();
                    } catch (IllegalAccessException e) {
                       // log.error("【excel导入】clazz映射地址：{},{}", clazz.getCanonicalName(), "excel导入异常！");
                        throw new SystemException(ErrorCode.SYS_EXCEPTION.getCode(), "excel导入异常", e);
                    } catch (InstantiationException e) {
                        //log.error("【excel导入】clazz映射地址：{},{}", clazz.getCanonicalName(), "excel导入异常！");
                        throw new SystemException(ErrorCode.SYS_EXCEPTION.getCode(), "excel导入异常", e);
                    }
                    for (int cellNum = 0; cellNum < firstLine; cellNum++) {
                        // 取出对应注解
                        Excel excel = fields[cellNum].getAnnotation(Excel.class);
                        Cell cell = row.getCell(cellNum);
                        if (rowNum == 0) {
                            // 第一行 判断表头名称
                            if (cell == null || StringUtils.isEmpty(cell.getStringCellValue()) || !cell.getStringCellValue().equals(excel.titleName())) {
                                throw new BizException(ErrorCode.SYS_EXCEPTION.getCode(), NAME_ERROR);
                            }
                            continue;
                        }
                        Object value = getCellValue(cell);
                        // 判断注解是否允许空值
                        if (!excel.empty()) {
                            if (value == null || "".equals(value)) {
                                throw new BizException(ErrorCode.SYS_EXCEPTION.getCode(), excel.titleName() + "不能为空");
                            }
                        }
                        // 根绝类型 实体类赋值
                        createBean(fields[cellNum], obj, value);
                    }
                    if (rowNum == 0) {
                        // 表头不做记录
                        continue;
                    }
                    list.add((T) obj);
                }
            }
        }
        return list;
    }

    /**
     * 导出模版
     *
     * @param excelName excel 名称
     * @param clazz     数据集
     * @param response  使用response可以导出到浏览器
     * @param <T>
     * @return
     */
    private static <T> Boolean exportTemplate(String excelName, Class<T> clazz, HttpServletResponse response) {
        return exportExcel(excelName, null, clazz, XLS, response, false);
    }

    /**
     * 导出模版
     *
     * @param excelName excel 名称
     * @param clazz     数据集
     * @param type      excel 类型
     * @param response  使用response可以导出到浏览器
     * @param <T>
     * @return
     */
    private static <T> Boolean exportTemplate(String excelName, Class<T> clazz, String type, HttpServletResponse response) {
        return exportExcel(excelName, null, clazz, type, response, false);
    }

    /**
     * excel 导出 （对象）
     *
     * @param excelName excel 名称
     * @param list      数据集
     * @param clazz     反射clazz
     * @param response  使用response可以导出到浏览器
     * @param <T>
     * @return
     */
    public static <T> Boolean exportExcel(String excelName, List<T> list, Class<T> clazz, HttpServletResponse response) {
        return exportExcel(excelName, list, clazz, XLS, response, true);
    }

    /**
     * excel 导出 （对象）
     *
     * @param excelName excel 名称
     * @param list      数据集
     * @param clazz     反射clazz
     * @param type      excel 类型
     * @param response  使用response可以导出到浏览器
     * @param <T>
     * @return
     */
    private static <T> Boolean exportExcel(String excelName, List<T> list, Class<T> clazz, String type, HttpServletResponse response) {
        return exportExcel(excelName, list, clazz, type, response, true);
    }
    
    /**
     * excel 导出 （Map）
     *
     * @param excelName excel 名称
     * @param clazz     反射clazz
     * @param list      数据集
     * @param response  使用response可以导出到浏览器
     * @param <T>
     * @return
     */
    private static <T> Boolean exportExcel(String excelName, Class<T> clazz, List<Map<String, Object>> list, HttpServletResponse response) {
        return exportExcel(excelName, clazz, list, XLS, response, true);
    }

    /**
     * excel 导出 （Map）
     *
     * @param excelName excel 名称
     * @param clazz
     * @param list      数据集
     * @param type      excel 类型
     * @param response  使用response可以导出到浏览器
     * @param <T>
     * @return
     */
    private static <T> Boolean exportExcel(String excelName, Class<T> clazz, List<Map<String, Object>> list, String type, HttpServletResponse response) {
        return exportExcel(excelName, clazz, list, type, response, false);
    }

    /**
     * excel 导出 （Map）
     *
     * @param excelName excel 名称
     * @param clazz
     * @param list      数据集
     * @param type      excel 类型
     * @param response  使用response可以导出到浏览器
     * @param flag      true：数据导出 false：模版导出
     * @param <T>
     * @return
     */
    private static <T> Boolean exportExcel(String excelName, Class<T> clazz, List<Map<String, Object>> list, String type, HttpServletResponse response, boolean flag) {
        if (list == null || list.size() == 0) {
            //log.error("【excel导出】{}", "excel导出数据空异常！");
            return false;
        }
        List<T> ts = JSONArray.parseArray(JSON.toJSONString(list), clazz);
        return exportExcel(excelName, ts, clazz, type, response, flag);
    }

    /**
     * excel 导出 （对象）
     *
     * @param excelName excel 名称
     * @param list      数据集
     * @param clazz     反射clazz
     * @param type      excel 类型
     * @param response  使用response可以导出到浏览器
     * @param flag      true：数据导出 false：模版导出
     * @param <T>
     * @return
     */
    private static <T> Boolean exportExcel(String excelName, List<T> list, Class<T> clazz, String type, HttpServletResponse response, boolean flag) {
        if (flag) {
            // 非模版导出，判断数据是否为空！
            if (list == null || list.size() == 0) {
                //log.error("【excel导出】{}", "excel导出数据空异常！");
                return false;
            }
        }
        // 设置默认文件名为当前时间：年月日时分秒
        if (StringUtils.isEmpty(excelName)) {
            //log.info("【excel导出】{}", "excel导出未设置文件名，默认使用时间戳代替！");
            excelName = new SimpleDateFormat("yyyyMMdd HHmmss").format(new Date());
        }
        createResponse(excelName, response, type);
        //获取对象总数量
        Field[] fields = getSortFields(clazz);
        Workbook workbook;
        switch (type) {
            case XLS:
                workbook = new HSSFWorkbook();
                break;
            case XLS_X:
                workbook = new XSSFWorkbook();
                break;
            default:
                //log.error("【excel导出】{}", "excel类型错误，只支持xls与xlsx！");
                return false;
        }
        // 创建一个工作表sheet 默认是表名是sheet0
        Sheet sheet = workbook.createSheet(excelName);
        setWorkBook(workbook, sheet, fields);
        try {
            if (flag) {
                // 开始生成excel
                for (int rowIndex = 1; rowIndex <= list.size(); rowIndex++) {
                    Object obj = list.get(rowIndex - 1);
                    Field[] sortFields = getSortFields(obj.getClass());
                    //创建第 rowIndex 行）
                    Row row = sheet.createRow(rowIndex);
                    for (int i = 0; i < sortFields.length; i++) {
                        Field field = sortFields[i];
                        if (!field.isAccessible()) {
                            field.setAccessible(true);
                        }
                        Object o = field.get(obj);// new java.beans.PropertyDescriptor(field.getName(), clazz).getReadMethod().invoke(obj);
                        if (!field.getAnnotation(Excel.class).empty() && o == null) {
                            //log.error("【excel导出】class映射地址：{},空指针参数：{},{}", clazz.getCanonicalName(), field.getName(), "数据集空指针");
                            return false;
                        }
                        setValue(getCell(workbook, row, i, o, field), o, field);
                    }
                }
            }
            //将文件输出
            OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
            return true;
        } catch (IOException e) {
            throw new SystemException(ErrorCode.SYS_EXCEPTION.getCode(), "excel导出异常", e);
        } catch (IllegalAccessException e) {
            throw new SystemException(ErrorCode.SYS_EXCEPTION.getCode(), "excel导出异常", e);
        } 
    }


//    ---------------------------------------------------- excel 工具 ------------------------------------------------------------------


    /**
     * 设置表格内容的值
     *
     * @param cell  单元格对象
     * @param value 单元格的值
     */
    private static void setValue(Cell cell, Object value, Field field) {
        if (value == null || "".equals(value)) {
            return;
        } else if (value instanceof String) {
            cell.setCellValue(value.toString());
        } else if (value instanceof Integer
                || value instanceof Double
                || value instanceof Float
                || value instanceof Long
                || value instanceof Short) {
            // 判断类型
            BigDecimal bi1 = new BigDecimal(value.toString());
            BigDecimal bi2 = new BigDecimal("10000");
            BigDecimal divide = bi1.divide(bi2, field.getAnnotation(Excel.class).type().decimalType().getScale(), RoundingMode.HALF_UP);
            cell.setCellValue(divide.doubleValue());
        } else if (value instanceof Date) {
            SimpleDateFormat sdf = new SimpleDateFormat(field.getAnnotation(Excel.class).type().timeType().getTimeType());
            cell.setCellValue(sdf.format((Date) value));
        }
    }

    /**
     * 设置excel单元格样式
     *
     * @param workbook
     * @param row
     * @param num
     * @param field
     * @return
     */
    private static Cell getCell(Workbook workbook, Row row, int num, Object value, Field field) {
        CellStyle cellStyle = getCellStyle(workbook);
        // 获取指定单元格
        Cell cell = row.createCell(num);
        // 设置类型
        DataFormat format = workbook.createDataFormat();
        if (value instanceof Integer
                || value instanceof Double
                || value instanceof Float
                || value instanceof Long) {
            cellStyle.setDataFormat(format.getFormat(field.getAnnotation(Excel.class).type().decimalType().getDecimal().toString()));
        } else if (value instanceof Date) {
            cellStyle.setDataFormat(format.getFormat(field.getAnnotation(Excel.class).type().timeType().getTimeType()));
        } else {
            cellStyle.setDataFormat(format.getFormat("@"));
        }
        cell.setCellStyle(cellStyle);
        return cell;
    }

    /**
     * 设置excel 样式 （第一行格式）
     *
     * @param workbook
     * @param sheet
     */
    private static void setWorkBook(Workbook workbook, Sheet sheet, Field[] fields) {
        CellStyle cellStyle = getCellStyle(workbook);
        //写入excel的表头（创建第一行）
        Row row = sheet.createRow(0);
        // 设置类型
        DataFormat format = workbook.createDataFormat();
        // 设置列宽、表头、数据类型
        for (int i = 0; i < fields.length; i++) {
            //设置宽度
            sheet.setColumnWidth(i, fields[i].getAnnotation(Excel.class).titleSize() * 256);
            //创建第一行
            Cell cell = row.createCell(i);
            //设置表头名称
            cell.setCellValue(fields[i].getAnnotation(Excel.class).titleName());
            cell.setCellStyle(cellStyle);
            cellStyle.setDataFormat(format.getFormat("@"));
            sheet.setDefaultColumnStyle(i, cellStyle);
        }
    }

    /**
     * 初始化样式属性
     *
     * @param workbook
     * @return
     */
    private static CellStyle getCellStyle(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        // 设置对齐方式为居中对齐
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        // 设置自动换行
        cellStyle.setWrapText(true);
        // 设置单元格内容垂直对其方式为居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // 设置字体
        Font font = workbook.createFont();
        font.setFontName("宋体");
        cellStyle.setFont(font);
        return cellStyle;
    }

    /**
     * 创建excel 导出 response信息
     *
     * @param excelName
     * @param response
     */
    private static void createResponse(String excelName, HttpServletResponse response, String type) {
        // 设置response头信息
        response.reset();
        // 改成输出excel文件
        response.setContentType("application/vnd.ms-excel");
        try {
            switch (type) {
                case XLS:
                    response.setHeader("Content-disposition", "attachment; filename="
                            + new String((excelName).getBytes("gb2312"), "ISO-8859-1") + ".xls");
                    break;
                case XLS_X:
                    response.setHeader("Content-disposition", "attachment; filename="
                            + new String((excelName).getBytes("gb2312"), "ISO-8859-1") + ".xlsx");
                    break;
                default:
                  //  log.error("【excel导出】{}", "excel类型错误，只支持xls与xlsx！");
                    throw new BizException(ErrorCode.SYS_EXCEPTION.getCode(), "excel类型错误，只支持xls与xlsx！");
            }
        } catch (UnsupportedEncodingException e) {
        //    log.error("【excel导出】{}", "设置response信息异常！");
            throw new SystemException(ErrorCode.SYS_EXCEPTION.getCode(), "设置response信息异常！", e);
        }
    }

    /**
     * 根据实体类型 赋值数据
     *
     * @param field
     * @param newInstance
     * @param value
     * @param <T>
     */
    private static <T> void createBean(Field field, T newInstance, Object value) {
        if (!field.isAccessible()) {
            field.setAccessible(true);
        }
        try {
            if (value == null) {
                field.set(newInstance, null);
            } else if (Long.class.equals(field.getType())) {
                field.set(newInstance, Long.valueOf(String.valueOf(value)));
            } else if (String.class.equals(field.getType())) {
                field.set(newInstance, String.valueOf(value));
            } else if (Integer.class.equals(field.getType())) {
                field.set(newInstance, Integer.valueOf(String.valueOf(value)));
            } else if (int.class.equals(field.getType())) {
                field.set(newInstance, Integer.parseInt(String.valueOf(value)));
            } else if (Date.class.equals(field.getType())) {
                field.set(newInstance, (Date) value);
            } else if (Boolean.class.equals(field.getType())) {
                field.set(newInstance, (Boolean) value);
            } else if (Double.class.equals(field.getType())) {
                field.set(newInstance, Double.valueOf(String.valueOf(value)));
            } else {
                field.set(newInstance, value);
            }
        } catch (IllegalAccessException e) {
           // log.error("【excel导入】clazz映射地址：{},{},{}", newInstance, "excel实体赋值类型转换异常！", e);
            throw new SystemException(ErrorCode.SYS_EXCEPTION.getCode(), "excel实体赋值类型转换异常", e);
        }
    }
        

	/**
     * 这是一个通用的方法，
     * @param sheetName
     *            表格sheet名
     * @param headers
     *            表格属性列名数组
     * @param headersField
     * 			  表格属性列名数组所对应的Map的Key值的集合
     * @param excelData
     *            需要显示的数据集合,集合中一定要放置符合Map风格的类的对象。此方法支持的
     *            javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
     * @param out
     *            与输出设备关联的流对象，可以将EXCEL文档导出到本地文件或者网络中
     * @param pattern
     *            如果有时间数据，设定输出格式。

	 * @throws Exception 
     */
    public void exportExcels(String sheetName,String[] headers,String[] headersField,List<Map<String, Object>> excelData,
    	String pattern,HttpServletResponse response) throws Exception{

    	// 声明一个工作薄

        HSSFWorkbook workbook = new HSSFWorkbook();

    	int iMaxLines = 65534;

        // 生成一个表格

    	int index = 0;

    	int page =1;

        HSSFSheet sheet = workbook.createSheet(sheetName);

        // 设置表格默认列宽度为15个字节

        sheet.setDefaultColumnWidth((int) 15);

        // 产生表格标题行

        HSSFRow row = sheet.createRow(0);

        for (int i = 0; i < headers.length; i++) {

            HSSFCell cell = row.createCell(i);

            HSSFRichTextString text = new HSSFRichTextString(headers[i]);

            cell.setCellValue(text);

        }

        // 遍历集合数据，产生数据行

    	Iterator<Map<String, Object>> it = excelData.iterator();

    	//String[] headersField = this.selectTableColumn(ztreeids);

    	

    	while (it.hasNext()) {

   	   	  index++;

          row = sheet.createRow(index);

          Map<String, Object> t =  it.next();

          int m=0;

      	  for(short n = 0;n<headersField.length;n++) {

      		  if(n==0)m=0;

              HSSFCell cell = row.createCell(m);

              m++;

              Object value = t.get(headersField[n]);

              // 判断值的类型后进行强制类型转换

              String textValue = null;

              if (value instanceof Date) {

                  Date date = (Date) value;

                  SimpleDateFormat sdf = new SimpleDateFormat(pattern);

                  textValue = sdf.format(date);

              } else {

                  // 其它数据类型都当作字符串简单处理

                  textValue = value==null?null:value.toString();

              }

              // 如果不是图片数据，就利用正则表达式判断textValue是否全部由数字组成

              if (textValue != null) {

                  Pattern p = Pattern.compile("^//d+(//.//d+)?{1}");

                  Pattern p1 = Pattern.compile("^\\d+$");

                  Matcher matcher = p.matcher(textValue);

                  Matcher matcher1 = p1.matcher(textValue);

                  if (matcher.matches()) {

                      // 是数字当作double处理

                      cell.setCellValue(Double.parseDouble(textValue));

                  }else {

                  	   if(matcher1.matches()){

                      	cell.setCellValue(Long.parseLong(textValue));

                       }else {

                          cell.setCellValue(textValue);

                       }

                  }

              }

          }

       }

        

		//将文件存到浏览器设置的下载位置 注释中为直接保存到后台设置的存储位置

		OutputStream out = response.getOutputStream();//获得输出流

		/*try {

			out = new FileOutputStream("D:"+sheetName+".xls");

			workbook.write(out);

			String str1 = "导出" + sheetName + "成功！";

			System.out.println(str1);

			out.close();

		} catch (Exception e) {

			e.printStackTrace();

			String str1 = "导出" + sheetName + "失败！";

			System.out.println(str1);

		} */


		response.reset();// 清空输出流

	    response.setContentType("application/msexcel");// 定义输出类型

 

		String filename = sheetName + ".xls";

		

		try {

			response.setContentType("application/ms-excel;charset=UTF-8");// 定义输出类型  ;charset=UTF-8

			response.addHeader("Content-Disposition", "attachment;filename="+

					 new String(filename.getBytes(), "iso-8859-1"));// 设定输出文件头  new String(filename.getBytes())

			

			workbook.write(out);// 将数据写出去

			String str = "导出" + sheetName + "成功！";

			System.out.println(str);

		} catch (Exception e) {

			e.printStackTrace();

			String str1 = "导出" + sheetName + "失败！";

			System.out.println(str1);

		} finally {

			out.close();

		}
 }	

 
    /**
     * 实体判空，注解判空
     *
     * @param clazz
     * @return
     */
    private static Field[] getSortFields(Class clazz) {
        //获取对象总数量
        Field[] fields = clazz.getDeclaredFields();
        if (fields == null || fields.length == 0) {
            //log.error("【excel导入】clazz映射地址：{},{}", clazz.getCanonicalName(), "实体空异常！");
            throw new BizException(ErrorCode.SYS_EXCEPTION.getCode(), BEAN_ERROR);
        }
        List<Field> ls=new ArrayList<Field>();

        for (int i=fields.length-1;i>=0;i--){
            if (fields[i].isAnnotationPresent(Excel.class)) {
                ls.add(fields[i]);
            }
        }
        /*for (Field field : fields) {
            if (!field.isAnnotationPresent(Excel.class)) {
              //log.error("【excel导入】clazz映射地址：{},{}", clazz.getCanonicalName(), "实体空Excel注解异常！");
                throw new BizException(ErrorCode.SYS_EXCEPTION.getCode(), ANNOTATION_ERROR);
            }
        }*/
        ls.sort((a, b) -> {
            return a.getAnnotation(Excel.class).orderNum() - b.getAnnotation(Excel.class).orderNum();
        });
        Field [] fs=new Field[ls.size()];
        return ls.toArray(fs);
    }

    /**
     * 列转化值
     *
     * @param cell 列值
     * @throws IOException
     */
    private static Object getCellValue(Cell cell) {
        Object cellValue = null;
        if (cell == null) {
            return cellValue;
        }

        // 把数字当成String来读，避免出现1读成1.0的情况
        // 判断数据的类型
        switch (cell.getCellType()) {
            case NUMERIC:
                if (cell.getCellType() == CellType.NUMERIC) {
                    if (DateUtil.isValidExcelDate(cell.getNumericCellValue())) {
                        CellStyle style = cell.getCellStyle();
                        if (style == null) {
                            return false;
                        }
                        int i = style.getDataFormat();
                        String f = style.getDataFormatString();
                        boolean isDate = DateUtil.isADateFormat(i, f);
                        if (isDate) {
                            Date date = cell.getDateCellValue();
                            return cellValue = date;
                        }
                    }
                }
                // 防止科学计数进入
                if (String.valueOf(cell.getNumericCellValue()).toLowerCase().contains(E)) {
                    throw new BizException(ErrorCode.SYS_EXCEPTION.getCode(), "excel数据类型错误，请将数字转文本类型！！");
                }
                if ((int) cell.getNumericCellValue() != cell.getNumericCellValue()) {
                    // double 类型
                    cellValue = cell.getNumericCellValue();
                } else {
                    cellValue = (int) cell.getNumericCellValue();
                }
                break;
            // 字符串
            case STRING:
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            // Boolean
            case BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            // 公式
            case FORMULA:
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            // 空值
            case BLANK:
                cellValue = null;
                break;
            // 故障
            case ERROR:
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }

    /**
     * 由文件生成 poi Workbook
     *
     * @param file
     * @return
     */
    private static Workbook getWorkBook(MultipartFile file) {
        // 获得文件名
        String fileName = file.getOriginalFilename();
        // 创建Workbook工作薄对象，表示整个excel
        Workbook workbook = null;
        // 获取excel文件的io流
        InputStream is = null;
        try {
            is = file.getInputStream();
            // 根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
            if (fileName.endsWith(XLS)) {
                // 2003
                workbook = new HSSFWorkbook(is);
            } else if (fileName.endsWith(XLS_X)) {
                // 2007
                workbook = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            throw new SystemException(ErrorCode.SYS_EXCEPTION.getCode(), "excel 转换 HSSFWorkbook 异常！", e);
        }
        return workbook;
    }

    /**
     * 检查文件
     *
     * @param file
     * @throws IOException
     */
    private static void checkFile(MultipartFile file) {
        // 判断文件是否存在
        if (null == file) {
            throw new BizException(ErrorCode.SYS_EXCEPTION.getCode(), FILE_NOT_ERROR);
        }
        // 获得文件名
        String fileName = file.getOriginalFilename();
        // 判断文件是否是excel文件
        if (!fileName.endsWith(XLS) && !fileName.endsWith(XLS_X)) {
            throw new BizException(ErrorCode.SYS_EXCEPTION.getCode(), fileName + "不是excel文件");
        }
    }
}

